package com.asen.commons.core.jdbc.handler;

import com.asen.commons.core.base.model.BaseEnumEntry;
import com.asen.commons.utils.BaseAssert;
import com.asen.commons.exception.TypeException;
import com.asen.commons.core.base.StringEnum;

import java.sql.*;

/**
 * StringEnum
 *
 * @author Gary
 * @version 1.0
 * @date 2018-11-29
 */
public class StringEnumHandler<E extends StringEnum> extends BaseTypeHandler<E> {

    private Class<E> type;
    private E[] enums;

    public StringEnumHandler() {
    }

    public StringEnumHandler(Class<E> type) {
        BaseAssert.notNull(type, "参数type不能为空");
        this.type = type;
        this.enums = type.getEnumConstants();
        BaseAssert.notNull(this.enums, type.getSimpleName() + "不是枚举类型");
    }

    @Override
    public int getSqlType() {
        return Types.VARCHAR;
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, StringEnum parameter)
            throws SQLException {
        ps.setString(i, parameter.getValue());
    }

    @Override
    public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String res = rs.getString(columnName);
        if (rs.wasNull()) {
            return null;
        }
        return getValue(res);
    }

    @Override
    public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String res = rs.getString(columnIndex);
        if (rs.wasNull()) {
            return null;
        }
        return getValue(res);
    }

    @Override
    public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String res = cs.getString(columnIndex);
        if (cs.wasNull()) {
            return null;
        }

        return getValue(res);
    }

    public E getValue(BaseEnumEntry value) {
        if (value == null) {
            return null;
        }

        for (E e : enums) {
            if (e.getValue().equals(value.getValue())) {
                return e;
            }
        }
        throw new TypeException("值【" + value + "】不能转换为枚举【" + type.getSimpleName() + "】");
    }

    @Override
    public E getValue(Object value) {
        if (value == null) {
            return null;
        }

        if (value instanceof String) {
            if (value.toString().trim().length() == 0) {
                return null;
            }
        }

        if (value instanceof BaseEnumEntry) {
            return getValue((BaseEnumEntry) value);
        }

        for (E e : enums) {
            if (e.getValue().equals(value.toString())) {
                return e;
            }
        }
        throw new TypeException("值【" + value + "】不能转换为枚举【" + type.getSimpleName() + "】");
    }

    @Override
    public String toSqlValue(Object value) {
        if (value == null) {
            return null;
        }

        if (value instanceof StringEnum) {
            return "\'" + ((StringEnum) value).getValue() + "\'";
        }

        if (value instanceof String) {
            if (value.toString().trim().length() == 0) {
                return null;
            }

            return "\'" + value + "\'";
        }

        if (value instanceof StringEnum[]) {
            StringBuilder sb = new StringBuilder(0);
            sb.append("(");
            for (StringEnum s : (StringEnum[]) value) {
                if (sb.length() > 0) {
                    sb.append(", ");
                }
                sb.append("\'" + s.getValue() + "\'");
            }
            sb.append(")");
            return sb.toString();
        }

        if (value instanceof String[]) {
            return getSqlValue((String[]) value, true);
        }

        return "\'" + value + "\'";
    }
}
